
package uk.org.cardboardbox.nfcpointstracker;

import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;

import uk.org.cardboardbox.nfcpointstracker.dialog.AddPointsDialog;
import uk.org.cardboardbox.nfcpointstracker.dialog.LoginDialog;
import uk.org.cardboardbox.nfcpointstracker.dialog.PinDialog;
import uk.org.cardboardbox.nfcpointstracker.dialog.UserDetailDialog;
import uk.org.cardboardbox.nfcpointstracker.dialog.WriteTagDialog;
import uk.org.cardboardbox.nfcpointstracker.model.Tag;

import android.app.AlertDialog;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.tech.NfcA;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;

import java.io.File;

public class MainActivity extends BaseActivity {

    private static final String TAG = MainActivity.class.getCanonicalName();

    private boolean loggedIn = false;

    private boolean ignoreTags = false;

    private boolean registerWaiting = false;

    private boolean writeWaiting = false;

    private AlertDialog registerDialog;

    private UserDetailDialog detailsDialog;

    private WriteTagDialog writeDialog;

    private File photoTemp;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.mainactivity);

    }

    @Override
    protected void onResume() {
        super.onResume();
        NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(this);

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
                getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        try {
            ndef.addDataType("*/*"); /*
                                      * Handles all MIME based dispatches. You
                                      * should specify only the ones that you
                                      * need.
                                      */
        } catch (MalformedMimeTypeException e) {
            throw new RuntimeException("fail", e);
        }
        IntentFilter[] intentFiltersArray = new IntentFilter[] {
            ndef,
        };
        String[][] techListsArray = new String[][] {
            new String[] {
                NfcA.class.getName()
            }
        };
        nfcAdapter
                .enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getSupportMenuInflater().inflate(R.menu.mainactivity, menu);

        if (loggedIn) {
            menu.removeItem(R.id.mainactivity_options_login);
            menu.removeItem(R.id.mainactivity_options_addpoints);
        } else {
            menu.removeItem(R.id.mainactivity_options_settings);
            menu.removeItem(R.id.mainactivity_options_registertag);
            menu.removeItem(R.id.mainactivity_options_managetags);
            menu.removeItem(R.id.mainactivity_options_logout);
        }

        return true;
    }

    private final void addPoints() {
        ignoreTags = true;
        new PinDialog(this, new PinDialog.Listener() {
            @Override
            public void onPinEntered(String pin) {
                new AddPointsDialog(MainActivity.this, new AddPointsDialog.Listener() {
                    @Override
                    public void onPointsSelected(int points) {
                        ignoreTags = false;
                        writeWaiting = true;
                        writeDialog = new WriteTagDialog(MainActivity.this);
                        writeDialog.show();
                    }

                    @Override
                    public void onCancelled() {
                        ignoreTags = false;
                    }
                }).show();
            }

            @Override
            public void onCancelled() {
                ignoreTags = false;
            }
        }).show();
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.mainactivity_options_addpoints:
                addPoints();
                break;
            case R.id.mainactivity_options_settings:
                settings();
                break;
            case R.id.mainactivity_options_login:
                login();
                break;
            case R.id.mainactivity_options_logout:
                logout();
                break;
            case R.id.mainactivity_options_registertag:
                registerTag();
                break;
            case R.id.mainactivity_options_about:
                about();
                break;

        }

        return super.onOptionsItemSelected(item);
    }

    private final void settings() {

    }

    private final void login() {
        new LoginDialog(this, new LoginDialog.Listener() {
            @Override
            public boolean onLogin(String username, String password) {
                loggedIn = true;
                supportInvalidateOptionsMenu();
                return false;
            }
        }).show();
    }

    private final void logout() {
        loggedIn = false;
        supportInvalidateOptionsMenu();
    }

    private final void registerTag() {
        registerWaiting = true;
        registerDialog = new AlertDialog.Builder(this).setTitle("Register Tag")
                .setMessage("Please scan a tag to continue")
                .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        registerWaiting = false;
                    }
                }).create();
        registerDialog.show();
    }

    private final void about() {
        new AlertDialog.Builder(this).setTitle("About").create().show();
    }

    private final void onNFCTagScanned() {

    }

    Tag tag = new Tag("xxx", "xxx");

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Log.d(TAG, "Got new intent");

        String action = intent.getAction();
        if (action.equals(NfcAdapter.ACTION_NDEF_DISCOVERED) && !ignoreTags) {
            onNFCTagScanned();
            if (registerWaiting) {
                registerDialog.dismiss();

                detailsDialog = new UserDetailDialog(MainActivity.this, tag,
                        new UserDetailDialog.Listener() {
                            @Override
                            public void onSelectPhoto() {
                                Log.d(TAG, "taking photo");
                                photoTemp = CameraUtils.getTempImageFile(MainActivity.this);
                                CameraUtils.takePhoto(MainActivity.this, photoTemp);
                            }
                        });
                detailsDialog.show();
            } else if (writeWaiting) {
                writeDialog.dismiss();
                writeWaiting = false;
            } else {
                Parcelable[] rawMsgs = intent
                        .getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
                Tag tag = Tag.fromNDEFMessage((NdefMessage)rawMsgs[0]);
                new AlertDialog.Builder(this).setTitle("Hello " + tag.getOwner())
                        .setMessage(String.format("You have %d points!", tag.getPoints()))
                        .setNeutralButton(android.R.string.ok, null).show();
            }
        }

    }

    private File cropTemp;

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.d(TAG, "onActivityResult");
        switch (requestCode) {
            case REQUESTCODE_TAKEPHOTO:
                if (resultCode == RESULT_OK) {
                    Log.d(TAG, "got photo");
                    cropTemp = CameraUtils.getTempImageFile(this);
                    CameraUtils.cropPhoto(this, photoTemp, cropTemp);
                } else
                    Log.d(TAG, "cancelled");
                break;
            case REQUESTCODE_CROP:
                if (resultCode == RESULT_OK) {
                    tag.setPhotoFromFile(cropTemp);
                    detailsDialog.onTagChanged();
                }
                break;

        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        NfcAdapter.getDefaultAdapter(this).disableForegroundDispatch(this);
    }

}
